package com.ruoyi.web.websocket;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.websocket.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * websocket 客户端用户集（支持多端多会话）
 */
public class WebSocketUsers {
    private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketUsers.class);

    // 一个用户 openId 对应多个 Session
    private static final Map<String, Set<Session>> USERS = new ConcurrentHashMap<>();

    /**
     * 存储用户 session
     *
     * @param key openId
     * @param session WebSocket 会话
     */
    public static void put(String key, Session session) {
        USERS.computeIfAbsent(key, k -> new CopyOnWriteArraySet<>()).add(session);
        LOGGER.info("添加用户 session [{}] - 当前会话数: {}", key, USERS.get(key).size());
    }

    /**
     * 移除用户 session（通过 Session）
     *
     * @param session WebSocket 会话
     * @return 移除的用户 key（openId），如果没找到返回 null
     */
    public static String removeBySession(Session session) {
        for (Map.Entry<String, Set<Session>> entry : USERS.entrySet()) {
            if (entry.getValue().remove(session)) {
                String key = entry.getKey();
                LOGGER.info("移除用户 session [{}] - 剩余会话数: {}", key, entry.getValue().size());
                if (entry.getValue().isEmpty()) {
                    USERS.remove(key);
                    LOGGER.info("用户 [{}] 已无活跃会话，已清理", key);
                }
                return key;
            }
        }
        return null;
    }

    /**
     * 获取所有 session（通过 openId）
     *
     * @param key openId
     * @return 该用户所有 session
     */
    public static Set<Session> get(String key) {
        return USERS.getOrDefault(key, Collections.emptySet());
    }

    /**
     * 获取所有在线用户
     *
     * @return 所有用户及其 session
     */
    public static Map<String, Set<Session>> getUsers() {
        return USERS;
    }

    /**
     * 通过 session 查找 openId
     *
     * @param session WebSocket 会话
     * @return openId，如果没找到返回 null
     */
    public static String getOpenIdBySession(Session session) {
        for (Map.Entry<String, Set<Session>> entry : USERS.entrySet()) {
            if (entry.getValue().contains(session)) {
                return entry.getKey();
            }
        }
        return null;
    }

    /**
     * 群发消息文本
     *
     * @param message 消息内容
     */
    public static void sendMessageToUsersByText(String message) {
        for (Set<Session> sessions : USERS.values()) {
            for (Session session : sessions) {
                sendMessageToUserByText(session, message);
            }
        }
    }

    /**
     * 向指定用户所有会话发送文本
     *
     * @param key openId
     * @param message 消息内容
     */
    public static void sendMessageToUserByText(String key, String message) {
        Set<Session> sessions = USERS.get(key);
        if (sessions != null && !sessions.isEmpty()) {
            for (Session session : sessions) {
                sendMessageToUserByText(session, message);
            }
        } else {
            LOGGER.info("[用户已离线] openId={}", key);
        }
    }

    /**
     * 向单个 session 发送文本
     *
     * @param session 会话
     * @param message 消息内容
     */
    public static void sendMessageToUserByText(Session session, String message) {
        if (session != null && session.isOpen()) {
            try {
                session.getBasicRemote().sendText(message);
            } catch (IOException e) {
                LOGGER.error("[发送消息异常]", e);
            }
        } else {
            LOGGER.info("[会话已关闭]");
        }
    }
}
